package com.authine.cloudpivot.engine.service.bizrule.handler;

import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.List;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.ParameterizedPreparedStatementSetter;

import com.authine.cloudpivot.engine.api.facade.BizObjectFacade;
import com.authine.cloudpivot.engine.domain.runtime.BizObject;
import com.authine.cloudpivot.engine.service.bizrule.handler.context.Request;
import com.authine.cloudpivot.foundation.util.api.SpringBeanUtils;
import com.authine.lib.utils.IdUtility;

/**
 * 定时归档处理任务
 *
 * @author LiuGangQiang Create in 2025/11/15
 */
public class 定时归档 extends BaseHandler {
    private static final Logger LOG = LoggerFactory.getLogger("在线编码-文档中心-菜单列表-定时归档");
    /**
     * 上级菜单 字段名 关联单选
     *
     * @author LiuGangQiang Create in 2025/11/15
     */
    private static final String SJCD_KEY = "ParentMenu";
    /**
     * 目标模型 字段名 单行文本
     *
     * @author LiuGangQiang Create in 2025/11/15
     */
    private static final String MBMX_SCHEMECODE = "SchemeCode";
    /**
     * 资料类型 字段名 关联单选
     *
     * @author LiuGangQiang Create in 2025/11/15
     */
    private static final String ZLLX_KEY = "FileType";
    /**
     * 归档表编码
     *
     * @author LiuGangQiang Create in 2025/11/15
     */
    private static final String ARCHIVING_SCHEMECODE = "ProjectFilearchiving";
    /**
     * 归档字段编码
     *
     * @author LiuGangQiang Create in 2025/11/15
     */
    private static final String ARCHIVING_FILED_CODE = "Attachments";
    /**
     * 专业序列ID 固定商务序列ID
     *
     * @author LiuGangQiang Create in 2025/11/15
     */
    private static final String SWXL_ID = "29e3aba7cef044a5801c7c3364534fb2";
    /**
     * 专业序列名称 固定商务序列
     *
     * @author LiuGangQiang Create in 2025/11/15
     */
    private static final String SWXL_NAME = "商务序列";
    /**
     * 文件归属KEY 固定项目部
     *
     * @author LiuGangQiang Create in 2025/11/15
     */
    private static final String WJGS_KEY = "code47013981378558";
    /**
     * 文件归属名称 固定项目部
     *
     * @author LiuGangQiang Create in 2025/11/15
     */
    private static final String WJGS_NAME = "项目部";
    /**
     * 每批次修改数量 指一次性修改数据库的行数 主要为解决性能问题 太小会增加对数据库的操作次数 太大单次执行响应更长 建议1000-3000
     *
     * @author LiuGangQiang Create in 2025/11/15
     */
    private static final Integer BATCHSIZE = 1000;

    @SuppressWarnings("unchecked")
    @Override
    public Object handle(Request request) {
        JdbcTemplate template = SpringBeanUtils.applicationContext.getBean(JdbcTemplate.class);
        BizObjectFacade facade = SpringBeanUtils.applicationContext.getBean(BizObjectFacade.class);
        /* 获取当前数据 */
        BizObject bizObject = request.getData().getBizObject();
        /* 解析当前触发条件数据 */
        Map<String, Object> data = bizObject.getData();
        /* 获取上级菜单 */
        final String SJCD = ((Map<String, Object>) data.get(SJCD_KEY)).get("id").toString();
        /* 获取目标模型编码 */
        String mbmx = data.get(MBMX_SCHEMECODE).toString();
        /* 获取上级菜单 */
        final String ZLLX = ((Map<String, Object>) data.get(ZLLX_KEY)).get("id").toString();
        /* 查询对应表单附件表 */
        String query = "SELECT hba.id,hba.bizObjectId,hba.`name`,hba.refId,hba.schemaCode,i.businessId,i.creater,i.createdDeptId,i.`owner`,"
                + "i.ownerDeptId,hba.createdTime,i.modifier,i.modifiedTime,i.ownerDeptQueryCode,hba.fileExtension,hba.fileSize,hba.base64ImageStr,"
                + "hba.mimeType,hba.parentBizObjectId,hba.parentSchemaCode FROM h_biz_attachment hba INNER JOIN " + facade.getTableName(mbmx)
                + " i ON i.id=hba.bizObjectId AND i.sequenceStatus=? WHERE hba.archiving = ? AND hba.schemaCode = ?";
        List<Map<String, Object>> files = template.queryForList(query, "COMPLETED", false, mbmx);
        files.forEach(file -> file.put("new_id", IdUtility.getUUID()));
        /* 批量插入数据到归档表 */
        String insert_gd = "INSERT INTO " + facade.getTableName(ARCHIVING_SCHEMECODE)
                + " (`id`, `name`, `creater`, `createdDeptId`, `owner`, `ownerDeptId`, `createdTime`, `modifier`, `modifiedTime`, `workflowInstanceId`, `sequenceNo`, `sequenceStatus`, `ownerDeptQueryCode`, `version`, `ProjectName`, `dataType`, `FileName`, `ProfessionalName`, `ProfessionalText`, `MenuName`, `FileLevel`, `Department`, `FileLevel_key`, `Department_q`)"
                + " VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
        template.batchUpdate(insert_gd, files, BATCHSIZE, new ParameterizedPreparedStatementSetter<Map<String, Object>>() {
            @Override
            public void setValues(PreparedStatement ps, Map<String, Object> data) throws SQLException {
                ps.setObject(1, data.get("new_id"));
                ps.setObject(2, data.get("name"));
                ps.setObject(3, data.get("creater"));
                ps.setObject(4, data.get("createdDeptId"));
                ps.setObject(5, data.get("owner"));
                ps.setObject(6, data.get("ownerDeptId"));
                ps.setObject(7, data.get("createdTime"));
                ps.setObject(8, data.get("modifier"));
                ps.setObject(9, data.get("modifiedTime"));
                ps.setObject(10, null);
                ps.setObject(11, IdUtility.getUUID());
                ps.setObject(12, "COMPLETED");
                ps.setObject(13, data.get("ownerDeptQueryCode"));
                ps.setObject(14, 4);
                ps.setObject(15, data.get("businessId"));
                ps.setObject(16, ZLLX);
                ps.setObject(17, data.get("name"));
                ps.setObject(18, SWXL_ID);
                ps.setObject(19, SWXL_NAME);
                ps.setObject(20, SJCD);
                ps.setObject(21, WJGS_NAME);
                ps.setObject(22, data.get("createdDeptId"));
                ps.setObject(23, WJGS_KEY);
                ps.setObject(24, null);
            }
        });

        /* 批量插入数据到文件表 */
        String insert_wj = "INSERT INTO `h_biz_attachment` (`id`, `bizObjectId`, `bizPropertyCode`, `createdTime`, `creater`, `fileExtension`, `fileSize`, `base64ImageStr`, `mimeType`, `name`, `parentBizObjectId`, `parentSchemaCode`, `refId`, `schemaCode`, `archiving`)"
                + "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
        template.batchUpdate(insert_wj, files, BATCHSIZE, new ParameterizedPreparedStatementSetter<Map<String, Object>>() {
            @Override
            public void setValues(PreparedStatement ps, Map<String, Object> data) throws SQLException {
                ps.setObject(1, IdUtility.getUUID());
                ps.setObject(2, data.get("new_id"));
                ps.setObject(3, ARCHIVING_FILED_CODE);
                ps.setObject(4, data.get("createdTime"));
                ps.setObject(5, data.get("creater"));
                ps.setObject(6, data.get("fileExtension"));
                ps.setObject(7, data.get("fileSize"));
                ps.setObject(8, data.get("base64ImageStr"));
                ps.setObject(9, data.get("mimeType"));
                ps.setObject(10, data.get("name"));
                ps.setObject(11, data.get("parentBizObjectId"));
                ps.setObject(12, data.get("parentSchemaCode"));
                ps.setObject(13, data.get("refId"));
                ps.setObject(14, ARCHIVING_SCHEMECODE);
                ps.setObject(15, true);
            }
        });

        /* 批量修改附件归档状态避免再次归档 */
        String update = "UPDATE h_biz_attachment SET archiving=? WHERE id=?";
        template.batchUpdate(update, files, BATCHSIZE, new ParameterizedPreparedStatementSetter<Map<String, Object>>() {
            @Override
            public void setValues(PreparedStatement ps, Map<String, Object> data) throws SQLException {
                ps.setObject(1, true);
                ps.setObject(2, data.get("id"));
            }
        });
        LOG.info("文件归档完成,本次归档表单：[{}] 归档文件数量：[{}]", mbmx, files.size());
        return bizObject;
    }
}
